"""
解码器
"""

import decimal
import json
import uuid
from datetime import (
    date,
    datetime,
    time,
    timedelta,
)

from django.db.models.query import QuerySet
from django.utils.encoding import force_str
from django.utils.functional import Promise


class JsonEncoder(json.JSONEncoder):
    """
    JSON 解码器
    """

    def default(self, obj):
        if isinstance(obj, Promise):
            return force_str(obj)
        elif isinstance(obj, (date, datetime, time)):
            return obj.isoformat()
        elif isinstance(obj, timedelta):
            return str(obj.total_seconds())
        elif isinstance(obj, decimal.Decimal):
            return float(obj)
        elif isinstance(obj, uuid.UUID):
            return str(obj)
        elif isinstance(obj, QuerySet):
            return tuple(obj)
        elif isinstance(obj, bytes):
            # Best-effort for binary blobs. See #4187.
            return obj.decode()
        elif hasattr(obj, "tolist"):
            # Numpy arrays and array scalars.
            return obj.tolist()
        elif hasattr(obj, "__getitem__"):
            cls = (
                list
                if isinstance(obj, (list, tuple, set))
                else dict
            )
            try:
                return cls(obj)
            except Exception:  # noqa
                pass
        elif hasattr(obj, "__iter__"):
            return tuple(item for item in obj)
        return super().default(obj)
